package language;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;

public class LNumber extends LMagnitude {

    public static final LNumber ZERO = new LNumber(0);
    public static final LNumber ONE = new LNumber(1);
    public static final LNumber PI = new LNumber(new BigDecimal("3.14159265358979323846264338327950288419716939937510582"));

    public LNumber(BigDecimal num) {
        super(num, false);
    }

    public LNumber(long num) {
        this(new BigDecimal(num));
    }

    public LNumber(double num) {
        this(new BigDecimal(num));
    }

    public LNumber(LMagnitude mag) {
        super(mag, false);
    }

    public static LNumber of(boolean num) {
        return num ? ONE : ZERO;
    }

    public static LNumber parse(LArray<LMagnitude> arr) {
        List<LMagnitude> list = arr.list();
        List<Character> chars = list.stream().map(LMagnitude::toChar).collect(Collectors.toList());
        boolean isExp = false;
        boolean isDec = false;
        boolean neg = chars.get(0).equals('-');
        if (neg) {
            chars.remove(0);
        }
        boolean negExp = false;
        int exp = 0;
        int dec = 0;
        String num = neg ? "-" : "";
        for (int i = 0; i < chars.size(); i++) {
            char c = chars.get(i);
            if ((c < '0' || c > '9') && c != 'e' && c != '.') {
                break;
            }
            if (c == 'e') {
                isExp = true;
                negExp = chars.get(i + 1).equals('-');
                if (negExp) {
                    i++;
                }
            } else if (c == '.') {
                isDec = true;
            } else {
                if (isExp) {
                    exp = 10 * exp + (c - '0');
                } else {
                    num += c;
                    if (isDec) {
                        dec++;
                    }
                }
            }
        }
        if (negExp) {
            exp = 0 - exp;
        }
        return new LNumber(new BigDecimal(new BigInteger(num), dec - exp));
    }
}
